package com.cats.bi.sqltool;


import com.cats.bi.sqltool.basic.AbstractSearchable;
import com.cats.bi.sqltool.basic.Column;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author wang jian
 * @Description
 * @create 2021/4/7
 */
public interface SQLString {
    /**
     * 转SQL
     *
     * @param sb
     */
    void toSql(StringBuilder sb);

    /**
     * as value
     *
     * @param v
     * @return
     */
    static SQLString asValue(Object v) {
        return sb -> sb.append(v);
    }

    /**
     * toString
     *
     * @param value
     * @return
     */
    static String toString(Object value) {
        StringBuilder sb = new StringBuilder();
        appendValue(sb, value);
        return sb.toString();
    }

    /**
     * 添加 database
     *
     * @param sb
     * @param database
     */
    static void appendDatabase(StringBuilder sb, String database) {
        sb.append('`').append(database).append('`');
    }

    /**
     * 追加 表
     *
     * @param sb
     * @param table
     */
    static void appendTable(StringBuilder sb, String table) {
        sb.append(table);
    }

    /**
     * 追加 列 col
     *
     * @param sb
     * @param column
     */
    static void appendColumn(StringBuilder sb, String column) {
        if (Column.ALL.equals(column)) {
            sb.append("*");
        } else {
            sb.append(column);
//            sb.append('`').append(column).append('`');
        }
    }

    /**
     * 追加 value
     *
     * @param sb
     * @param value
     */
    static void appendValue(StringBuilder sb, Object value) {
        if (value == null) {
            sb.append("NULL");
        } else if (value instanceof Integer || !(value instanceof AbstractSearchable)) {

            if (value instanceof SQLString) {
                ((SQLString) value).toSql(sb);
            } else if (value instanceof Date) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                value = sdf.format((Date) value);
                appendValue(sb, value);
            } else {
                // as String
                sb.append('\'');
                String out = value.toString().replace("'", "\\'");
                sb.append(out);
                sb.append('\'');
            }
        } else if (value instanceof Number) {
            sb.append(value);
        } else {
            AbstractSearchable<?> select = (AbstractSearchable) value;
            sb.append('(');
            select.toSql(sb);
            sb.append(')');
        }
    }
}